//
//  SJEmoticonPackage.swift
//  表情处理
//
//  Created by app;e on 15/10/18.
//  Copyright © 2015年 world. All rights reserved.
//
/**
说明：
1. Emoticons.bundle 的根目录下存放的 emoticons.plist 保存了 packages 表情包信息
packages 是一个数组
字典中的属性 id 对应的分组路径的名称
2. 在 id 对应的目录下，各自都保存有 info.plist
group_name_cn   保存的是分组名称
emoticons       保存的是表情信息数组
code            UNICODE 编码字符串
chs             表情文字，发送给新浪微博服务器的文本内容
png             表情图片，在 App 中进行图文混排使用的图片
*/



import UIKit
// MARK: - 表情包类
class SJEmoticonPackage: NSObject {

    //表情路径
    var id:String?
    //表情分组的名称
    var groupName: String?
    ///表情数组(存放SJEmoticon 的数组)
    var emoticons:[SJEmoticon]?
    
    //根据id 创建对象 的初始化方法
    init(id:String?) {
        self.id = id
    }
    
    /// 添加喜爱的表情
    func addFavouriteEmoticon(emoticon:SJEmoticon){
        //判断 传人的表情  是否在 当前最近 表情包数组中
        let isContain = emoticons?.contains(emoticon)
        
        //将传人的表情,添加到当前表情包数组中
        if isContain == false{
            //不在 最近数组中 添加到该数组中
            emoticons?.append(emoticon)
        }
        
        // 保存排序后的结果
        var result = emoticons
        // 按照使用频率排序
        result = result?.sort{ $0.times > $1.times}
        
        if isContain == false{
            // 删除最后一个表情
            result?.removeLast()
        }
        emoticons = result
    }
    
    ///加载表情包数组 - 只有在第一次使用的时候,会实例化
    static let packageList = SJEmoticonPackage.packages()
    
    ///加载表情包数组 返回 表情包数组
   private class func packages() -> [SJEmoticonPackage]{
        
        //0. 创建一个存放表情包的数组
        var list = [SJEmoticonPackage]()
        
        //0.5. 添加最近表情包
        //创建最近表情包实例对象 id 为nil
        let recent = SJEmoticonPackage(id: nil)
        recent.groupName = "最近"
        //追加表情
        recent.appendEmptyEmoticons()
        list.append(recent)
        
        //1.读取 Emoticons.bundle 下的 emoticon.plist
        let path = NSBundle.mainBundle().pathForResource("emoticons.plist", ofType: nil, inDirectory: "Emoticons.bundle")
//        let array = NSArray(contentsOfFile: path!) //为nil 因为plist根为字典
        //2.从 path 下加载plist文件
        let dictionary = NSDictionary(contentsOfFile: path!)!
        //packegs 为存放 [String:AnyObject] 的数组
        let packages = dictionary["packages"] as! [[String:AnyObject]]
        
        //遍历 数组 将 字典转换成 SJEmoticonPackage 模型
        for emotionDic in packages{
            //根据id 初始化SJEmoticonPackage 对象
            let package = SJEmoticonPackage(id: emotionDic["id"] as! String)
        
            // 加载id对应的表情包(emoticons) (会调用三次)
            package.loadEmoticons()
            // 追加空白表情
            package.appendEmptyEmoticons()
            
            // 将表情包 添加 到表情包 数组中
            list.append(package)
        }
        
        return list
    }
    
    
    
    /// 加载对应的表情数组
    //  每20个表情按钮 添加一个删除按钮
    private func loadEmoticons(){
        //加载 id 对应的 info.plist (根为字典)
        let dictionary = NSDictionary(contentsOfFile: infoPlistPath())!
        //设置分组名
        groupName = dictionary["group_name_cn"] as? String
        //创建表情数组
        let array = dictionary["emoticons"] as! [[String:String]]

        //实例化表情数组
        emoticons = [SJEmoticon]()
        
        //遍历 数组  将array中的字典 转换成  SJEmoticon模型
        var index = 0
        for emoDict in array{
            let emoti = SJEmoticon(id: id, dict: emoDict)
            emoticons?.append(emoti)
            index++
            if index == 20 { //每20个表情按钮 添加一个删除按钮
                emoticons?.append(SJEmoticon(isRemovButton: true))
                index = 0 //将索引置0
            }
        }
    }
    ///追加空白按钮,方便界面布局,如果一个界面表情不足20个
    ///不足20个表情按钮 再添加一个删除按钮
    private func appendEmptyEmoticons(){
        
        if emoticons == nil {//如果没有emoticons 为最近 则 创建一个空的数组
            emoticons = [SJEmoticon]()
        }
        
        let count = emoticons!.count % 21 //由于在调用该方法的时候,已经先调用了loadEmoticons 在loadEmoticons方法中为每20个表情添加了一个 删除按钮 所以需要 %21  %21其实求的是该组表情包最后一页的表情的个数
        
        if count > 0 || emoticons!.count == 0 { //当count > 0 说明表情数 不能被21 整出 也就是说最后一页需要添加空白表情按钮   另外如果 emoticons!.count == 0 说明是最初的最近表情包
            for _ in count..<20 {
                emoticons?.append(SJEmoticon(isRemovButton: false))
            }
            //满20后 再最后追加一个删除按钮
            emoticons?.append(SJEmoticon(isRemovButton: true))
        }
    }
    
    ///返回info.plist的路径
    private func infoPlistPath()->String{
        return SJEmoticonPackage.emoticonsBundlePath().stringByAppendingString("/\(id!)").stringByAppendingString("/info.plist")
    }
    /// 返回表情包路径
    private class func emoticonsBundlePath() ->String{
        return NSBundle.mainBundle().bundlePath.stringByAppendingString("/Emoticons.bundle")
    }
}

// MARK: - 表情类
class SJEmoticon: NSObject{
    
    ///用来记录 表情的使用次数
    var times: Int = 0
    
    ///用来存放表情图片 的路径(表情 类别  标识)
    var id:String?
    ///表情文字，发送给新浪微博服务器的文本内容
    var chs:String?
    ///表情图片，在 App 中进行图文混排使用的图片
    var png:String?
    ///图片的完整路径
    var imagePath: String? {
        return png == nil ? nil : SJEmoticonPackage.emoticonsBundlePath().stringByAppendingString("/\(id!)").stringByAppendingString("/\(png!)")
    }
    
    //UNICODE 编码字符串
    var code:String?{
        didSet{
            //2.拿到数字
            //2.1 扫描器,可以扫描指定字符串中特定的文字
            let scanner = NSScanner(string: code!)
            //2.2 扫描整数
            var result:UInt32 = 0
            scanner.scanHexInt(&result)
//            print(result)
            //3 生成字符串 UNICODE 字符 -> 字符串
            emoji = "\(Character(UnicodeScalar(result)))"

        }
    }
    //emoji 表情 编码 对应的 字符串
    var emoji:String?
    //是否是删除按钮标记
    var removeButton = false
    
    //删除按钮模型 构造方法
    init(isRemovButton:Bool){
        removeButton = isRemovButton
    }
    
    //表情模型的构造方法
    init(id:String?, dict:[String:AnyObject]){
        super.init() //KVC必须要调用父类的方法
        self.id = id
        setValuesForKeysWithDictionary(dict)
    }
    // 字典转模型 如果字典中的key 比模型中的key 多 就会出现 有未定义的key
    //'[<Ë°®ÊÉÖÂ§ÑÁêÜ.SJEmoticon 0x7f9ee956b7c0> setValue:forUndefinedKey:]: this class is not key value coding-compliant for the key cht.'
    // 只要重写 setValueforUndefinedKey  如果过滤掉未定义的key
    override func setValue(value: AnyObject?, forUndefinedKey key: String) {
//        print(key)
    }
}

